﻿namespace WenAntdUI.Settings;

public class AppSettings
{
    private static readonly IFreeSql fsql = new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.Sqlite, "DataSource=settings.db")
    .UseAdoConnectionPool(true)
#if DEBUG
    .UseMonitorCommand(cmd => Console.WriteLine($"Setting Sql：{cmd.CommandText}\r\n"))
#endif
    .UseAutoSyncStructure(true) //自动同步实体结构到数据库，只有CRUD时才会生成表
    .Build();
    private static List<Setting>? settings;

    public static IFreeSql FSql => fsql;

    /// <summary>
    /// 全部设置内容
    /// </summary>
    public static List<Setting> Settings => settings ??= fsql.Select<Setting>().ToList();

    /// <summary>
    /// 获取设置值，若存在设置，读取数据中的值，不存在创建并返回初始化指定值
    /// </summary>
    /// <param name="name"></param>
    /// <param name="value"></param>
    /// <param name="displayname"></param>
    /// <param name="groupname"></param>
    /// <returns></returns>
    public static string GetOrSet(string name, string value, string displayname, string groupname)
    {
        var stt = GetString(name);
        if (stt == null)
        {
            SetString(name, value, displayname, groupname);
        }
        return stt ?? value;
    }

    /// <summary>
    /// 获取设置实例
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static Setting? GetSetting(string name) => Settings.Where(t => t.Name == name).FirstOrDefault();

    /// <summary>
    /// 获取设置String值
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static string? GetString(string name) => GetSetting(name)?.Value;

    public static bool GetBool(string name) => Get<bool>(name);

    /// <summary>
    /// 修改设置值，不存在自动新增
    /// </summary>
    /// <param name="name"></param>
    /// <param name="value"></param>
    /// <param name="displayname"></param>
    /// <param name="groupname"></param>
    public static void SetString(string name, string value, string displayname = "", string groupname = "", Type? type = null)
    {
        var stt = fsql.Select<Setting>().Where(t => t.Name == name).First();
        if (stt is null)
        {
            stt = new Setting()
            {
                DisplayName = displayname,
                Name = name,
                Value = value,
                GroupName = groupname,
                Type = (type ?? typeof(string)).AssemblyQualifiedName,
            };
            fsql.Insert<Setting>().AppendData(stt).ExecuteAffrows();
        }
        else
        {
            stt.Value = value;
            if (!string.IsNullOrWhiteSpace(displayname))
            {
                stt.DisplayName = displayname;
            }
            if (!string.IsNullOrWhiteSpace(groupname))
            {
                stt.GroupName = groupname;
            }
            fsql.Update<Setting>().SetSource(stt).ExecuteAffrows();
        }
        settings = null;
    }

    public static void Set<T>(string name, T t, string displayname = "")
    {
        var value = string.Empty;
        if (typeof(T) == typeof(Color))
        {
            if (t is Color color)
                value = ColorTranslator.ToHtml(color);
        }
        else
        {
            value = t.ToString();
        }
        SetString(name, value, displayname, type: typeof(T));
    }

    public static T Get<T>(string name)
    {
        var stt = GetSetting(name);
        if (stt is null)
        {
            return default(T);
        }
        var input = stt.Value;
        var type = typeof(T);
        try
        {
            // 处理Color类型
            if (type == typeof(Color))
            {
                return (T)(object)ColorTranslator.FromHtml(input);
            }

            // 处理布尔类型（如"true"或"1"）
            if (type == typeof(bool))
            {
                if (input.Equals("1")) return (T)(object)true;
                if (input.Equals("0")) return (T)(object)false;
                return (T)(object)bool.Parse(input);
            }

            // 处理枚举类型
            if (type.IsEnum)
            {
                return (T)Enum.Parse(type, input, true);
            }

            // 处理基础类型（int/float等）
            return (T)Convert.ChangeType(input, type);
        }
        catch
        {
            return default(T);
        }
    }
}